﻿using CommandProcessor.Dispatcher;
using Data.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PagedList;
using AutoMapper;
using QuanLySanXuat.Models;
using Domain.Commands;
using Core.Common;
using Core.Extensions;
using Data.Models;

namespace QuanLySanXuat.Controllers
{
    public class ProductModelController : Controller
    {
        private readonly ICommandBus commandBus;
        private readonly IProductModelRepository procductModelRepository;
        private readonly ICategoryRepository categoryRepository;
        private readonly IProductTypeRepository productTypeRepository;
        private readonly IDesignDetailRepository designDetailRepository;
        private readonly IMaterialFormulaRepository materialFormulaRepository;
        private readonly ILabourFormulaRepository labourFormulaRepository;
        private readonly IToolFormulaRepository toolFormulaRepository;
        private readonly IOtherCostFormulaRepository othercostFormulaRepository;
        private readonly IMaterialTypeRepository materialTypeRepository;
        private readonly IUOMRepository uomRepository;
        private readonly IToolTypeRepository toolTypeRepository;
        private readonly IWorkerLevelRepository labourRepository;
        private readonly IOtherCostRepository otherCostRepository;
        //
        // GET: /ProductModel/
        public ProductModelController(ICommandBus commandBus, IProductModelRepository procductModelRepository, ICategoryRepository categoryRepository, IProductTypeRepository productTypeRepository, IDesignDetailRepository designDetailRepository, IMaterialTypeRepository materialTypeRepository, IUOMRepository uomRepository, IMaterialFormulaRepository materialFormulaRepository, ILabourFormulaRepository labourFormulaRepository, IToolFormulaRepository toolFormulaRepository, IOtherCostFormulaRepository othercostFormulaRepository, IToolTypeRepository toolTypeRepository, IWorkerLevelRepository labourRepository, IOtherCostRepository otherCostRepository)
        {
            //Phai khoi tao moi dung duoc
            this.commandBus = commandBus;
            this.procductModelRepository = procductModelRepository;
            this.categoryRepository = categoryRepository;
            this.productTypeRepository = productTypeRepository;
            this.designDetailRepository = designDetailRepository;
            this.materialTypeRepository = materialTypeRepository;
            this.uomRepository = uomRepository;
            this.materialFormulaRepository = materialFormulaRepository;
            this.labourFormulaRepository = labourFormulaRepository;
            this.toolFormulaRepository = toolFormulaRepository;
            this.othercostFormulaRepository = othercostFormulaRepository;
            this.toolTypeRepository = toolTypeRepository;
            this.labourRepository = labourRepository;
            this.otherCostRepository = otherCostRepository;
        }
        public ActionResult Index()
        {
            var productModel = procductModelRepository.GetAll().OrderBy(x=>x.Code);
            return View(productModel.ToPagedList(1, 10));
        }
        public ActionResult Create(int? ID)
        {
            ViewData["Category"] = categoryRepository.GetAll();
            ViewData["ProductType"] = productTypeRepository.GetAll();

            ViewData["DesignDetail"] = designDetailRepository.GetMany(x => x.ProductModelID == ID);

            ViewData["UOM"] = uomRepository.GetAll();
            ViewData["MaterialType"] = materialTypeRepository.GetAll();
            ViewData["ToolType"] = toolTypeRepository.GetAll();
            ViewData["Labour"] = labourRepository.GetAll();
            ViewData["Other"] = otherCostRepository.GetAll();
            var productModel = procductModelRepository.GetById(ID ?? 0);
            var productForms = Mapper.Map<ProductModel, ProductModelFormModels>(productModel);
            if (productModel != null)
            {
                //Lay ra chi tiet design
                var designDetail = designDetailRepository.GetMany(x => x.ProductModelID == productModel.ID);
                productForms.DesignDetailFormModels = designDetail;
                //Lay ra chi tiet cog thuc nguyen vat lieu
                var materialFormula=materialFormulaRepository.GetMany(x => x.ProductModelID == productModel.ID);
                productForms.MaterialFormulaFormModels=materialFormula;
                //Lay ra chi tiet cog thuc nguyen vat lieu
                var toolFormula=toolFormulaRepository.GetMany(x => x.ProductModelID == productModel.ID);
                productForms.ToolFormulaFormModels=toolFormula;
                //Lay ra chi tiet cog thuc nguyen vat lieu
                var labourFormula=labourFormulaRepository.GetMany(x => x.ProductModelID == productModel.ID);
                productForms.LabourFormulaFormModels=labourFormula;
                //Lay ra chi tiet cog thuc nguyen vat lieu
                var otherFormula=othercostFormulaRepository.GetMany(x => x.ProductModelID == productModel.ID);
                productForms.OtherCostFormulaFormModels = otherFormula;
            }

            //Xoa het bang DesgiDetail ghi tam voi ProductModelID=0
            var designDetail1 = designDetailRepository.GetMany(x => x.ProductModelID == 0);
            if (designDetail1.Count() > 0)
            {
                List<DeleteDesignDetailCommand> list = new List<DeleteDesignDetailCommand>();
                foreach (var item in designDetail1)
                {
                    var cmd = new DeleteDesignDetailCommand { ID = item.ID };
                    list.Add(cmd);
                }
                commandBus.SubmitRange(list);
            }
            return View(productForms);
        }
        [HttpPost]
        public ActionResult Save(ProductModelFormModels frm)
        {
            //Them vao productmodel
            var form = new ProductModelFormModels()
            {
                ID = frm.ID,
                Author = frm.Author,
                Catalogue = frm.Catalogue,
                CatDate = frm.CatDate,
                CategoryID = frm.CategoryID,
                Code = frm.Code,
                Date = frm.Date,
                Description = frm.Description,
                Note = frm.Note,
                ProductTypeID = frm.ProductTypeID,
                Name=frm.Name
            };
            var command = Mapper.Map<ProductModelFormModels, CreateOrUpdateProductModelCommand>(form);
            IEnumerable<ValidationResult> errors = commandBus.Validate(command);
            ModelState.AddModelErrors(errors);
            if (ModelState.IsValid)
            {
                var result = commandBus.Submit(command);
            
                //Xoa het bang DesgiDetail ghi tam voi ProductModelID=0
                var designDetail1 = designDetailRepository.GetMany(x => x.ProductModelID == 0);
                if(designDetail1.Count()>0)
                {
                    List<DeleteDesignDetailCommand> list = new List<DeleteDesignDetailCommand>();
                    foreach (var item in designDetail1)
                    {
                        var cmd = new DeleteDesignDetailCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }


                //Them vao bang bang DesgiDetail ghi tam voi ProductModel hien tai
                if (frm.designID != null)
                {
                    for (int i = 0; i < frm.designID.Length; i++)
                    {
                        if(frm.designID[i]!=0)
                        {
                            int typeID = 0;
                            if (frm.TypeID != null)
                            {
                                typeID = frm.TypeID[i];
                            }
                            var frmDetail = new DesginDetailFormModels()
                            {
                                Code=frm.CodeDesgin[i],
                                Description=frm.DescriptionDesign[i],
                                DesignFile=frm.DesignFile[i],
                                ID=frm.designID[i],
                                Name=frm.NameDesign[i],
                                ProductModelID=result.ID,
                                Type=typeID,
                            };
                            var cmdDesgin = Mapper.Map<DesginDetailFormModels, CreateOrUpdateDesignDetailCommand>(frmDetail);
                            commandBus.Submit(cmdDesgin);
                        }
                    }
                }

                //Them vao bang MaterialFormula
                if (frm.MaterialFormulaID != null)
                {
                    var lstMater = new List<CreateOrUpdateMaterialFormulaCommand>();
                    for (int i = 0; i < frm.MaterialFormulaID.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(frm.CodeMaterialFormula[i]))
                        {
                            int typeID = 0;
                            if (frm.MaterialTypeID != null)
                            {
                                typeID = frm.MaterialTypeID[i];
                            }

                            var frmDetail = new MaterialFormulaFormModels()
                            {
                                Code = frm.CodeMaterialFormula[i],
                                ID = frm.MaterialFormulaID[i],
                                Name = frm.NameMaterialFormula[i],
                                ProductModelID = result.ID,
                                DesignDetailID = frm.MaterialDesignDetailID[i],
                                MaterialTypeID = typeID,
                                Quantity = frm.QuantityMaterialFormula[i],
                                UOMID = frm.MaterialUOMID[i]

                            };
                            var cmdMater = Mapper.Map<MaterialFormulaFormModels, CreateOrUpdateMaterialFormulaCommand>(frmDetail);
                            lstMater.Add(cmdMater);
                        }
                           
                    }
                    commandBus.SubmitRange(lstMater);
                }

                //Them vao bang LabourFormula
                if (frm.LabourFormulaID != null)
                {
                    var lstLabour = new List<CreateOrUpdateLabourFormulaCommand>();
                    for (int i = 0; i < frm.LabourFormulaID.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(frm.CodeLabourFormula[i]))
                        {
                            int typeID = 0;
                            if (frm.LabourTypeID != null)
                            {
                                typeID = frm.LabourTypeID[i];
                            }

                            var frmDetail = new LabourFormulaFormModels()
                            {
                                Code = frm.CodeLabourFormula[i],
                                ID = frm.LabourFormulaID[i],
                                Name = frm.NameLabourFormula[i],
                                ProductModelID = result.ID,
                                DesignDetailID = frm.LabourDesignDetailID[i],
                                WorkerLevelID = typeID,
                                Quantity = frm.QuantityLabourFormula[i],
                                UOMID = frm.LabourUOMID[i]

                            };
                            var cmdMater = Mapper.Map<LabourFormulaFormModels, CreateOrUpdateLabourFormulaCommand>(frmDetail);
                            lstLabour.Add(cmdMater);
                        }
                    }
                    commandBus.SubmitRange(lstLabour);
                }
                //Them vao bang ToolFormula
                if (frm.ToolFormulaID != null)
                {
                    var lstTool = new List<CreateOrUpdateToolFormulaCommand>();
                    for (int i = 0; i < frm.ToolFormulaID.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(frm.CodeToolFormula[i]))
                        {
                            int typeID = 0;
                            if (frm.ToolTypeID != null)
                            {
                                typeID = frm.ToolTypeID[i];
                            }

                            var frmDetail = new ToolFormulaFormModels()
                            {
                                Code = frm.CodeToolFormula[i],
                                ID = frm.ToolFormulaID[i],
                                Name = frm.NameToolFormula[i],
                                ProductModelID = result.ID,
                                DesignDetailID = frm.ToolDesignDetailID[i],
                                ToolTypeID = typeID,
                                Quantity = frm.QuantityToolFormula[i],
                                UOMID = frm.ToolUOMID[i]

                            };
                            var cmdMater = Mapper.Map<ToolFormulaFormModels, CreateOrUpdateToolFormulaCommand>(frmDetail);
                            lstTool.Add(cmdMater);
                        }
                    }
                    commandBus.SubmitRange(lstTool);
                }
                //Them vao bang OtherFormula
                if (frm.OtherFormulaID != null)
                {
                    var lstOther = new List<CreateOrUpdateOtherCostFormulaCommand>();
                    for (int i = 0; i < frm.OtherFormulaID.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(frm.CodeOtherFormula[i]))
                        {
                            int typeID = 0;
                            if (frm.OtherTypeID != null)
                            {
                                typeID = frm.OtherTypeID[i];
                            }

                            var frmDetail = new OtherCostFormulaFormModels()
                            {
                                Code = frm.CodeOtherFormula[i],
                                ID = frm.OtherFormulaID[i],
                                Name = frm.NameOtherFormula[i],
                                ProductModelID = result.ID,
                                DesignDetailID = frm.OtherDesignDetailID[i],
                                OtherCostID = typeID,
                                Quantity = frm.QuantityOtherFormula[i],
                                UOMID = frm.OtherUOMID[i],
                            };
                            var cmdMater = Mapper.Map<OtherCostFormulaFormModels, CreateOrUpdateOtherCostFormulaCommand>(frmDetail);
                            lstOther.Add(cmdMater);
                        }
                    }
                    commandBus.SubmitRange(lstOther);
                }
            }
            return RedirectToAction("Index");
        }
        [HttpPost]
        public JsonResult UpdateDesignDetail(int ID, string Code, string Name, string Description, string DesignFile, int Type, int ProductID)
        {
            int desginID = 0;//Tra ve' ID cho hiden desginID
            var command = new CreateOrUpdateDesignDetailCommand()
            {
                Code=Code,
                Description=Description,
                DesignFile=DesignFile,
                Name=Name,
                Type = Type,
                ProductModelID = ProductID,
                ID = ID
            };
            IEnumerable<ValidationResult> errors = commandBus.Validate(command);
            ModelState.AddModelErrors(errors);
            if (ModelState.IsValid)
            {
                desginID = commandBus.Submit(command).ID;
            }
            ViewData["DesignDetail"] = designDetailRepository.GetAll();
            return Json(desginID);
        }

        [HttpPost]
        public ActionResult RemoveItems(string[] ProID)
        {
            List<DeleteProductModelCommand> listt = new List<DeleteProductModelCommand>();
            foreach (var e in ProID)
            {
                var productModelID = int.Parse(e);
                

                //Xoa vao bang MaterialFormual ghi tam voi ProductModel hien tai
                var formual = materialFormulaRepository.GetMany(x => x.ProductModelID == productModelID);
                if (formual.Count() > 0)
                {
                    List<DeleteMaterialFormulaCommand> list = new List<DeleteMaterialFormulaCommand>();
                    foreach (var item in formual)
                    {
                        var cmd = new DeleteMaterialFormulaCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }

                //Xoa vao bang TollFormual ghi tam voi ProductModel hien tai
                var tool = toolFormulaRepository.GetMany(x => x.ProductModelID == productModelID);
                if (tool.Count() > 0)
                {
                    List<DeleteToolFormulaCommand> list = new List<DeleteToolFormulaCommand>();
                    foreach (var item in tool)
                    {
                        var cmd = new DeleteToolFormulaCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }

                //Xoa vao bang OtherFormual ghi tam voi ProductModel hien tai
                var other = othercostFormulaRepository.GetMany(x => x.ProductModelID == productModelID);
                if (other.Count() > 0)
                {
                    List<DeleteOtherCostFormulaCommand> list = new List<DeleteOtherCostFormulaCommand>();
                    foreach (var item in other)
                    {
                        var cmd = new DeleteOtherCostFormulaCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }

                //Xoa vao bang LabourFormual ghi tam voi ProductModel hien tai
                var labour = labourFormulaRepository.GetMany(x => x.ProductModelID == productModelID);
                if (labour.Count() > 0)
                {
                    List<DeleteLabourFormulaCommand> list = new List<DeleteLabourFormulaCommand>();
                    foreach (var item in labour)
                    {
                        var cmd = new DeleteLabourFormulaCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }
                var command = new DeleteProductModelCommand { ID = productModelID };
                listt.Add(command);

                //Xoa het bang DesgiDetail ghi tam voi ProductModelID
                var designDetail1 = designDetailRepository.GetMany(x => x.ProductModelID == productModelID);
                if (designDetail1.Count() > 0)
                {
                    List<DeleteDesignDetailCommand> list = new List<DeleteDesignDetailCommand>();
                    foreach (var item in designDetail1)
                    {
                        var cmd = new DeleteDesignDetailCommand { ID = item.ID };
                        list.Add(cmd);
                    }
                    commandBus.SubmitRange(list);
                }
            }
            //Xoa bang prodcut model
            commandBus.SubmitRange(listt);
            var model = procductModelRepository.GetAll();

            
            return PartialView("_ProductModelList", model.ToPagedList(1, 10));
        }
        [HttpPost]
        public JsonResult Remove(int ID)
        {
            //Xoa het bang MaterialFormula co DesignDetailID bi xoa
            var materialFormula = materialFormulaRepository.GetMany(x => x.DesignDetailID == ID);
            if (materialFormula.Count() >0)
            {
                List<DeleteMaterialFormulaCommand> list = new List<DeleteMaterialFormulaCommand>();
                foreach (var item in materialFormula)
                {
                    var cmd = new DeleteMaterialFormulaCommand { ID = item.ID };
                    list.Add(cmd);
                }
                commandBus.SubmitRange(list);
            }
            

            //Xoa het bang ToolFormula co DesignDetailID bi xoa
            var toolFormula = toolFormulaRepository.GetMany(x => x.DesignDetailID == ID);
            if (toolFormula.Count()>0)
            {
                List<DeleteToolFormulaCommand> lstTool = new List<DeleteToolFormulaCommand>();
                foreach (var item in toolFormula)
                {
                    var cmd = new DeleteToolFormulaCommand { ID = item.ID };
                    lstTool.Add(cmd);
                }
                commandBus.SubmitRange(lstTool);
            }
           

            //Xoa het bang LabourFormula co DesignDetailID bi xoa
            var labourFormula = labourFormulaRepository.GetMany(x => x.DesignDetailID == ID);
            if (labourFormula.Count()>0)
            {
                List<DeleteLabourFormulaCommand> lstLabour = new List<DeleteLabourFormulaCommand>();
                foreach (var item in labourFormula)
                {
                    var cmd = new DeleteLabourFormulaCommand { ID = item.ID };
                    lstLabour.Add(cmd);
                }
                commandBus.SubmitRange(lstLabour);
            }
            

            //Xoa het bang OtherCostFormula co DesignDetailID bi xoa
            var otherFormula = othercostFormulaRepository.GetMany(x => x.DesignDetailID == ID);
            if (otherFormula.Count()>0)
            {
                List<DeleteOtherCostFormulaCommand> lstOther = new List<DeleteOtherCostFormulaCommand>();
                foreach (var item in otherFormula)
                {
                    var cmd = new DeleteOtherCostFormulaCommand { ID = item.ID };
                    lstOther.Add(cmd);
                }
                commandBus.SubmitRange(lstOther);
            }

            //Xoa het bang DesignDetail
            var command = new DeleteDesignDetailCommand { ID = ID};
            commandBus.Submit(command);
            //Thieu phan cap nhat lai grid nua
            return Json(true);
        }
        [HttpPost]
        public JsonResult RemoveDesign(string Code, string Name, int DesignID)
        {
            if (Name == "tblMaterial")
            {
                var materialFormula = materialFormulaRepository.GetMany(x => x.Code == Code&&x.DesignDetailID==DesignID).FirstOrDefault();
                if (materialFormula != null)
                {
                    var command = new DeleteMaterialFormulaCommand { ID = materialFormula.ID };
                    commandBus.Submit(command);
                }
               
            }
            else if (Name == "tblTool")
            {
                 var toolFormula = toolFormulaRepository.GetMany(x => x.Code == Code&& x.DesignDetailID==DesignID).FirstOrDefault();
                 if (toolFormula != null)
                 {
                     var command = new DeleteToolFormulaCommand { ID = toolFormula.ID };
                     commandBus.Submit(command);
                 }
                
            }
            else if (Name == "tblLabour")
            {
                 var labourFormula = labourFormulaRepository.GetMany(x => x.Code == Code&&x.DesignDetailID==DesignID).FirstOrDefault();
                 if (labourFormula != null)
                 {
                     var command = new DeleteLabourFormulaCommand { ID = labourFormula.ID };
                     commandBus.Submit(command);
                 }
                
            }
            else if(Name == "tblOther")
            {
                 var otherFormula = othercostFormulaRepository.GetMany(x => x.Code == Code&&x.DesignDetailID==DesignID).FirstOrDefault();
                 if (otherFormula != null)
                 {
                     var command = new DeleteOtherCostFormulaCommand { ID = otherFormula.ID };
                     commandBus.Submit(command);
                 }
            }
            return Json(true);
        }
        [HttpGet]
        public JsonResult GetDesignDetail(int ID, int ProductID)
        {
            var desginDetail = designDetailRepository.GetById(ID);
            if (desginDetail != null)
            {
                return Json(designDetailRepository.GetMany(x => x.ProductModelID == desginDetail.ProductModelID) as IEnumerable<Data.Models.DesignDetail>, JsonRequestBehavior.AllowGet);
            }
            else 
            {
                return Json(designDetailRepository.GetMany(x => x.ProductModelID == ProductID) as IEnumerable<Data.Models.DesignDetail>, JsonRequestBehavior.AllowGet);
            }
        }
        [HttpGet]
        public ActionResult GetNewRowDesignDetail()
        { 
            return View();
        }
        [HttpGet]
        public ActionResult Search(string Name)
        {
            IEnumerable<ProductModel> model;
            if (String.IsNullOrEmpty(Name))
            {
                model = procductModelRepository.GetAll();
            }
            else
            {
                model = procductModelRepository.GetMany(x => (x.Name.Contains(Name)) || (x.Description.Contains(Name)) || (x.Code.Contains(Name)));

            }
            return PartialView("_ProductModelList", model.ToPagedList(1, 10));
        }
        [HttpGet]
        [ValidateInput(false)]
        public ActionResult Page(int PageID)
        {
            var prodcutType = procductModelRepository.GetAll();
            return PartialView("_ProductModelList", prodcutType.ToPagedList(1, PageID));
        }

        [HttpGet]
        public JsonResult GetUOM(int Code, string Name)
        {
            int uomID = 0;
            if (Name == "tblMaterial")
            {
                uomID = materialTypeRepository.GetById(Code).UOMID ??0;

            }
            else if (Name == "tblTool")
            {
                uomID = toolTypeRepository.GetById(Code).UOMID;

            }
            else if (Name == "tblLabour")
            {
                uomID = labourRepository.GetById(Code).UOMID ?? 0;

            }
            else if (Name == "tblOther")
            {
                uomID = otherCostRepository.GetById(Code).UOMID;
            }
            return Json(uomID, JsonRequestBehavior.AllowGet);
        }
    }
}
